-
Notifications
You must be signed in to change notification settings - Fork 415
Update channel_reestablish
for splicing
#3886
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
🎉 This PR is now ready for review! |
🔔 1st Reminder Hey @wpaulino! This PR has been waiting for your review. |
06c0dfc
to
f000b76
Compare
@wpaulino Ready for review now. |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3886 +/- ##
==========================================
- Coverage 89.66% 89.42% -0.24%
==========================================
Files 164 165 +1
Lines 134661 126319 -8342
Branches 134661 126319 -8342
==========================================
- Hits 120743 112967 -7776
+ Misses 11237 10971 -266
+ Partials 2681 2381 -300 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
🔔 2nd Reminder Hey @wpaulino! This PR has been waiting for your review. |
🔔 3rd Reminder Hey @wpaulino! This PR has been waiting for your review. |
🔔 4th Reminder Hey @wpaulino! This PR has been waiting for your review. |
🔔 5th Reminder Hey @wpaulino! This PR has been waiting for your review. |
🔔 6th Reminder Hey @wpaulino! This PR has been waiting for your review. |
While splicing is not yet fully supported, checking if the feature has been negotiated is needed for changes to the channel_reestablish logic.
The splicing spec extends the channel_reestablish message with two more TLVs indicating which funding txid the sender has sent/received either explicitly via splice_locked or implicitly via channel_ready. This allows peers to detect if a splice_locked was lost during disconnection and must be retransmitted. This commit updates channel_reestablish with the TLVs. Subsequent commits will implement the spec requirements.
The previous commit extended the channel_reestablish message with your_last_funding_locked_txid and my_current_funding_locked_txid for use as described there. This commit sets those fields to the funding txid most recently sent/received accordingly.
When splicing is negotiated, channel_ready must be retransmitted when your_last_funding_locked is not set. Further, the current logic for retransmitting channel_ready is only applicable when splicing is not negotiated.
The splicing spec updates the logic pertaining to next_funding_txid when handling a channel_reestablish message. Specifically: A receiving node: - if `next_funding_txid` is set: - if `next_funding_txid` matches the latest interactive funding transaction or the current channel funding transaction: - if `next_commitment_number` is equal to the commitment number of the `commitment_signed` message it sent for this funding transaction: - MUST retransmit its `commitment_signed` for that funding transaction. - if it has already received `commitment_signed` and it should sign first, as specified in the [`tx_signatures` requirements](#the-tx_signatures-message): - MUST send its `tx_signatures` for that funding transaction. - if it has already received `tx_signatures` for that funding transaction: - MUST send its `tx_signatures` for that funding transaction. - if it also sets `next_funding_txid` in its own `channel_reestablish`, but the values don't match: - MUST send an `error` and fail the channel. - otherwise: - MUST send `tx_abort` to let the sending node know that they can forget this funding transaction. This commit updates FundedChannel::channel_reestablish accordingly. Co-authored-by: Wilmer Paulino <[email protected]> Co-authored-by: Jeffrey Czyz <[email protected]>
The splicing spec updates the logic pertaining to next_commitment_number when sending a channel_reestablish message. Specifically: The sending node: - if it has sent `commitment_signed` for an interactive transaction construction but it has not received `tx_signatures`: - MUST set `next_funding_txid` to the txid of that interactive transaction. - if it has not received `commitment_signed` for that interactive transaction: - MUST set `next_commitment_number` to the commitment number of the `commitment_signed` it sent.
The channel_reestablish protocol supports retransmitting splice_locked messages as needed. Add support for doing such when handling channel_reestablish messages.
The splicing spec updates channel_establishment logic to retransmit channel_ready or splice_locked for announced channels. Specifically: - if `my_current_funding_locked` is included: - if `announce_channel` is set for this channel: - if it has not received `announcement_signatures` for that transaction: - MUST retransmit `channel_ready` or `splice_locked` after exchanging `channel_reestablish`.
When a splice transaction is promoted (i.e., when splice_locked has been exchanged), announcement_signatures must be sent. However, if we try to send a channel_announcement before they are received, then the signatures will be incorrect. To avoid this, clear the counterparty's announcement_signatures upon promoting a FundingScope.
The channel_reestablish protocol supports retransmitting channel_ready messages as needed. Add support for doing such when handling channel_reestablish messages.
When handling a counterparties channel_reestablish, the spec dictates that a splice_locked may be implied by my_current_funding_locked. Compare that against any pending splices and handle an implicit splice_locked message when applicable.
f000b76
to
e2ea3bf
Compare
Rebased. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may need to double check our incoming channel_ready
handling to make sure we can handle receiving one long after channel_ready
was already exchanged due to the new logic surrounding your_last_funding_locked_txid
.
@@ -80,6 +80,8 @@ | |||
//! (see [BOLT-2](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#channel-quiescence) for more information). | |||
//! - `ZeroFeeCommitments` - A channel type which always uses zero transaction fee on commitment transactions. | |||
//! (see [BOLT PR #1228](https://github.com/lightning/bolts/pull/1228) for more info). | |||
//! - `Splice` - Allows replacing the funding transaction with a new one |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
//! - `Splice` - Allows replacing the funding transaction with a new one | |
//! - `Splice` - Allows replacing the currently-locked funding transaction with a new one |
@@ -1665,12 +1665,12 @@ where | |||
/// send our peer to begin the channel reconnection process. | |||
#[rustfmt::skip] | |||
pub fn peer_connected_get_handshake<L: Deref>( | |||
&mut self, chain_hash: ChainHash, logger: &L, | |||
&mut self, chain_hash: ChainHash, features: &InitFeatures, logger: &L, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remote_features
*
#[cfg(not(splicing))] | ||
fn maybe_get_your_last_funding_locked_txid(&self, _features: &InitFeatures) -> Option<Txid> { | ||
None | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we could avoid the not(splicing)
variants by just doing this inline above
@@ -9381,6 +9381,13 @@ where | |||
self.context.latest_inbound_scid_alias.or(self.funding.get_short_channel_id()) | |||
} | |||
|
|||
/// Returns true if their channel_ready has been received | |||
#[cfg(splicing)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed
@@ -10128,10 +10135,52 @@ where | |||
} | |||
} | |||
|
|||
#[cfg(splicing)] | |||
fn maybe_get_your_last_funding_locked_txid(&self, features: &InitFeatures) -> Option<Txid> { | |||
if !features.supports_splicing() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the TLVs are optional, I don't think we really need to check this and can always set them
msg.your_last_funding_locked_txid | ||
.is_none() | ||
.then(|| ()) | ||
.and_then(|_| self.get_channel_ready(logger)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I would've expected this to check that we can actually send channel_ready
, but we don't seem to check it above either...
&& !session.has_received_commitment_signed() | ||
{ | ||
// FIXME | ||
return unimplemented!(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI
self.pending_funding | ||
.iter() | ||
.find(|funding| funding.get_funding_txid() == Some(funding_txid)) | ||
.and_then(|_| { | ||
self.pending_splice.as_ref().and_then(|pending_splice| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason to iterate over pending_funding
when we know it should exist if a splice_locked
was sent for it?
.find(|funding| funding.get_funding_txid() == Some(funding_txid)) | ||
.and_then(|_| { | ||
self.pending_splice.as_ref().and_then(|pending_splice| { | ||
(Some(funding_txid) != pending_splice.received_funding_txid) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be checking sent_funding_txid
instead? Isn't this handling the case where we sent our splice_locked
, didn't get to process theirs even though they sent it, and are now reconnecting?
if let Some(splice_locked) = implicit_splice_locked { | ||
self.internal_splice_locked(counterparty_node_id, &splice_locked)?; | ||
} | ||
|
||
Ok(NotifyOption::SkipPersistHandleEvents) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to persist if we promoted the scope above
👋 The first review has been submitted! Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer. |
The splicing spec extends the
channel_reestablish
message with two more TLVs indicating which funding txid the sender has sent/received either explicitly viasplice_locked
or implicitly viachannel_ready
. This allows peers to detect if asplice_locked
was lost during disconnection and must be retransmitted.To this end, the spec updates the
channel_reestablish
logic to support splicing.